#!/bin/bash
set -eo pipefail

# ================= 样式定义 =================
RED='\033[31m'
GREEN='\033[32m'
YELLOW='\033[33m'
BOLD='\033[1m'
RESET='\033[0m'

info() { echo -e "${BOLD}🌀 ${1}${RESET}"; }
success() { echo -e "${GREEN}✅ ${1}${RESET}"; }
warning() { echo -e "${YELLOW}⚠️  ${1}${RESET}"; }
error() { echo -e "${RED}❌ ${1}${RESET}" >&2; }

# ================= 系统检测 =================
detect_os() {
    if [ -f /etc/os-release ]; then
        . /etc/os-release
        OS_TYPE="${ID}"
    else
        OS_TYPE=$(uname -s | tr '[:upper:]' '[:lower:]')
    fi

    case $OS_TYPE in
        ubuntu|debian|linuxmint) echo "debian";;
        centos|rhel|fedora|amzn) echo "rhel";;
        *) echo "unknown";;
    esac
}

# ================= 依赖安装 =================
install_package() {
    local pkg=$1
    case $(detect_os) in
        debian)
            sudo apt-get -qq update >/dev/null
            sudo DEBIAN_FRONTEND=noninteractive apt-get -qq install -y "$pkg"
            ;;
        rhel)
            sudo yum -q makecache >/dev/null
            sudo yum -q install -y "$pkg"
            ;;
        *)
            error "不支持的Linux发行版"
            return 1
            ;;
    esac
}

handle_dependencies() {
    declare -a missing_pkgs
    local os_type=$(detect_os)

    # 定义依赖映射表
    declare -A pkg_map=(
        ["lsof:debian"]="lsof"
        ["lsof:rhel"]="lsof"
        ["jq:debian"]="jq"
        ["jq:rhel"]="jq"
    )

    # 检查依赖项
    check_dep() {
        local cmd=$1 pkg_key=$2
        if ! command -v "$cmd" >/dev/null; then
            local pkg="${pkg_map["${pkg_key}:${os_type}"]}"
            if [ -n "$pkg" ]; then
                missing_pkgs+=("$pkg")
            else
                error "无法自动安装的依赖: $cmd"
                return 1
            fi
        fi
    }

    check_dep lsof lsof
    check_dep jq jq

    if [ ${#missing_pkgs[@]} -gt 0 ]; then
        warning "发现未安装的依赖项：${missing_pkgs[*]}"
        read -rp "是否自动安装？[Y/n] " answer
        case "$answer" in
            [Nn]*) 
                echo -e "\n手动安装指南："
                case "$os_type" in
                    debian) echo "sudo apt install ${missing_pkgs[*]}";;
                    rhel)   echo "sudo yum install ${missing_pkgs[*]}";;
                esac
                exit 1
                ;;
            *)
                for pkg in "${missing_pkgs[@]}"; do
                    info "正在安装：$pkg"
                    if ! install_package "$pkg"; then
                        error "安装失败: $pkg"
                        exit 1
                    fi
                done
                ;;
        esac
    fi
}

# ================= 主逻辑 =================
main() {
    # 预检依赖项
    handle_dependencies

    # ================= 配置区 =================
    PROJECT_ROOT="$(cd "$(dirname "$0")"; pwd)"
    CONFIG_FILE="${PROJECT_ROOT}/frontend/forum/public/config.json"
    IP=$(jq -r '.server.ip' "$CONFIG_FILE")
    BACKEND_PORT=$(jq -r '.server.backendPort' "$CONFIG_FILE")
    FRONTEND_PORT=$(jq -r '.server.frontendPort' "$CONFIG_FILE")
    FRONTEND_DIR="${PROJECT_ROOT}/frontend/forum/src"
    BACKEND_DIR="${PROJECT_ROOT}/backend/src"
    PID_DIR="${PROJECT_ROOT}/pids"

    # ================= 警告信息 =================
    echo -e "${BOLD}================================================================"
    echo "== 注意: 本脚本可能需要调用 sudo 权限，仅用于检验端口占用情况 =="
    echo "===-----------   查询端口列表如下：{$FRONTEND_PORT, $BACKEND_PORT}   -----------==="
    echo -e "================================================================${RESET}"

    mkdir -p "$PID_DIR" || { error "目录创建失败"; exit 1; }

    # ================ 功能函数 =================
    force_kill_by_port() {
        local port=$1
        info "强制清理端口 $port 占用进程..."
        sudo lsof -i TCP:"$port" -s TCP:LISTEN | awk 'NR>1 {print $2}' | xargs -r sudo kill -9
    }

    start_service() {
        local name="$1" port="$2" cmd="$3" work_dir="$4"
        local pid_file="${PID_DIR}/${name}.pid"

        if [ -f "$pid_file" ] && kill -0 "$(cat "$pid_file")" 2>/dev/null; then
            info "${name}已在运行 (PID: $(cat "$pid_file"))"
            return 0
        fi

        if lsof -i :"$port" >/dev/null; then
            warning "端口 $port 已被占用，自动清理中..."
            force_kill_by_port "$port"
        fi

        info "启动 ${name}..."
        (
            cd "$work_dir" || { error "无法进入目录: $work_dir"; exit 1; }
            setsid $cmd > /dev/null 2>&1 &
            echo $! > "$pid_file"
        )
        success "${name}启动成功 (PID: $(cat "$pid_file"))"
    }

    check_port() {
        local port=$1
        local retries=5 delay=2

        for ((i=1; i<=retries; i++)); do
            if sudo lsof -i TCP:"$port" -s TCP:LISTEN >/dev/null 2>&1; then
                success "端口 ${port} 监听正常"
                return 0
            else
                [ $i -lt $retries ] && sleep "$delay"
            fi
        done
        
        error "端口 ${port} 未监听！"
        return 1
    }

    # =============== 服务启动 ================
    start_service "frontend" "$FRONTEND_PORT" "npm run serve" "$FRONTEND_DIR"
    start_service "backend" "$BACKEND_PORT" "./a.out" "$BACKEND_DIR"

    check_port "$FRONTEND_PORT"
    check_port "$BACKEND_PORT"

    # =============== 最终输出 ================
    echo -e "${BOLD}****************************************************************${RESET}"
    echo -e "${GREEN}===   如果两个端口都在监听状态，则项目启动成功并运行在后台   ===${RESET}"
    echo -e "${BOLD}===          前端监听端口: $FRONTEND_PORT，后端监听端口: $BACKEND_PORT          ===${RESET}"
    echo -e "${BOLD}===           使用 http://${IP}:$FRONTEND_PORT 访问             ===${RESET}"
    echo -e "${BOLD}===        管理员页面: http://${IP}:$FRONTEND_PORT/login        ===${RESET}"
    echo -e "${BOLD}****************************************************************${RESET}"
    info "注意：IP地址自动获取，如需自定义部署请更新以下文件中的IP和端口："
    echo -e "${YELLOW}- $CONFIG_FILE${RESET}"
    echo -e "${BOLD}================== Coding with ❤  by zoufeng ====================${RESET}"
}

main